package com.ias.business.testbiz.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ias.business.testbiz.entity.TestBizEntity;
import com.ias.business.testbiz.service.TestBizService;
import com.ias.business.testbiz.service.impl.TestBizServiceImpl;
import com.ias.common.result.Result;
import com.ias.common.result.PageResult;
import com.ias.common.utils.page.PageUtil;
import com.ias.common.request.PageRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 测试业务管理控制器
 * 演示baomidou动态数据源的使用
 * 
 * @author IAS Team
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/test-biz")
@RequiredArgsConstructor
@Tag(name = "测试业务管理", description = "测试业务管理相关接口")
public class TestBizController {

    private final TestBizService testBizService;
    private final TestBizServiceImpl testBizServiceImpl;

    /**
     * 分页查询测试业务列表 - 演示从库查询
     * 基于MyBatis-Plus 3.5.9优化，使用标准分页参数
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询测试业务", description = "使用从库查询测试业务列表，支持关键词搜索")
    public Result<PageResult<TestBizEntity>> getTestBizPage(@Valid PageRequest pageRequest) {
        
        log.info("分页查询测试业务，页码：{}，每页大小：{}，关键词：{}", 
                pageRequest.getCurrentSafe(), pageRequest.getSizeSafe(), pageRequest.getKeywordSafe());
        
        Page<TestBizEntity> page = new Page<>(pageRequest.getCurrentSafe(), pageRequest.getSizeSafe());
        IPage<TestBizEntity> result = testBizService.selectTestBizPage(page, pageRequest.getKeywordSafe());
        
        // 转换为标准分页结果
        PageResult<TestBizEntity> pageResult = PageUtil.convertFromIPage(result);
        
        return Result.success(pageResult);
    }

    /**
     * 分页查询测试业务列表 - 兼容原有接口
     * 保持向后兼容性
     */
    @GetMapping("/page/legacy")
    @Operation(summary = "分页查询测试业务(兼容接口)", description = "兼容原有的分页查询接口")
    public Result<PageResult<TestBizEntity>> getTestBizPageLegacy(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1", name = "current") Long current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10", name = "size") Long size,
            @Parameter(description = "搜索关键词") @RequestParam(required = false, name = "keyword") String keyword) {
        
        log.info("兼容接口 - 分页查询测试业务，页码：{}，每页大小：{}，关键词：{}", current, size, keyword);
        
        // 创建分页请求对象
        PageRequest pageRequest = new PageRequest();
        pageRequest.setCurrent(current);
        pageRequest.setSize(size);
        pageRequest.setKeyword(keyword);
        
        return getTestBizPage(pageRequest);
    }

    /**
     * 根据ID查询测试业务详情 - 演示从库查询
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询测试业务详情", description = "使用从库根据ID查询测试业务详情")
    public ResponseEntity<Map<String, Object>> getTestBizById(
            @Parameter(description = "业务ID") @PathVariable Long id) {
        
        log.info("查询测试业务详情，ID：{}", id);
        
        TestBizEntity entity = testBizService.getById(id);
        
        Map<String, Object> response = new HashMap<>();
        if (entity != null) {
            response.put("code", 200);
            response.put("message", "查询成功");
            response.put("data", entity);
        } else {
            response.put("code", 404);
            response.put("message", "测试业务不存在");
            response.put("data", null);
        }
        response.put("dataSource", "slave");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 根据业务编码查询测试业务 - 演示从库查询
     */
    @GetMapping("/code/{bizCode}")
    @Operation(summary = "根据业务编码查询测试业务", description = "使用从库根据业务编码查询测试业务")
    public ResponseEntity<Map<String, Object>> getTestBizByCode(
            @Parameter(description = "业务编码") @PathVariable String bizCode) {
        
        log.info("根据业务编码查询测试业务：{}", bizCode);
        
        TestBizEntity entity = testBizServiceImpl.getByBizCode(bizCode);
        
        Map<String, Object> response = new HashMap<>();
        if (entity != null) {
            response.put("code", 200);
            response.put("message", "查询成功");
            response.put("data", entity);
        } else {
            response.put("code", 404);
            response.put("message", "测试业务不存在");
            response.put("data", null);
        }
        response.put("dataSource", "slave");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 统计测试业务数量 - 演示从库查询
     */
    @GetMapping("/count")
    @Operation(summary = "统计测试业务数量", description = "使用从库统计测试业务数量")
    public ResponseEntity<Map<String, Object>> countTestBiz() {
        
        log.info("统计测试业务数量");
        
        long count = testBizServiceImpl.countTestBiz();
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200);
        response.put("message", "统计成功");
        response.put("data", count);
        response.put("dataSource", "slave");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 创建测试业务 - 演示主库写入
     */
    @PostMapping
    @Operation(summary = "创建测试业务", description = "使用主库创建测试业务")
    public ResponseEntity<Map<String, Object>> createTestBiz(
            @Valid @RequestBody TestBizEntity entity) {
        
        log.info("创建测试业务：{}", entity.getBizName());
        
        boolean success = testBizService.save(entity);
        
        Map<String, Object> response = new HashMap<>();
        if (success) {
            response.put("code", 200);
            response.put("message", "创建成功");
            response.put("data", entity);
        } else {
            response.put("code", 500);
            response.put("message", "创建失败");
            response.put("data", null);
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 更新测试业务 - 演示主库写入
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新测试业务", description = "使用主库更新测试业务")
    public ResponseEntity<Map<String, Object>> updateTestBiz(
            @Parameter(description = "业务ID") @PathVariable Long id,
            @Valid @RequestBody TestBizEntity entity) {
        
        log.info("更新测试业务，ID：{}", id);
        
        entity.setId(id);
        boolean success = testBizService.updateById(entity);
        
        Map<String, Object> response = new HashMap<>();
        if (success) {
            response.put("code", 200);
            response.put("message", "更新成功");
            response.put("data", entity);
        } else {
            response.put("code", 500);
            response.put("message", "更新失败");
            response.put("data", null);
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 删除测试业务 - 演示主库写入
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除测试业务", description = "使用主库删除测试业务（逻辑删除）")
    public ResponseEntity<Map<String, Object>> deleteTestBiz(
            @Parameter(description = "业务ID") @PathVariable Long id) {
        
        log.info("删除测试业务，ID：{}", id);
        
        boolean success = testBizService.removeById(id);
        
        Map<String, Object> response = new HashMap<>();
        if (success) {
            response.put("code", 200);
            response.put("message", "删除成功");
        } else {
            response.put("code", 500);
            response.put("message", "删除失败");
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 更新业务状态 - 演示主库写入
     */
    @PutMapping("/{id}/status")
    @Operation(summary = "更新业务状态", description = "使用主库更新业务状态")
    public ResponseEntity<Map<String, Object>> updateStatus(
            @Parameter(description = "业务ID") @PathVariable Long id,
            @Parameter(description = "状态") @RequestParam Integer status) {
        
        log.info("更新业务状态，ID：{}，状态：{}", id, status);
        
        boolean success = testBizServiceImpl.updateStatus(id, status);
        
        Map<String, Object> response = new HashMap<>();
        if (success) {
            response.put("code", 200);
            response.put("message", "状态更新成功");
        } else {
            response.put("code", 500);
            response.put("message", "状态更新失败");
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 批量创建测试业务 - 演示主库批量写入
     */
    @PostMapping("/batch")
    @Operation(summary = "批量创建测试业务", description = "使用主库批量创建测试业务")
    public ResponseEntity<Map<String, Object>> batchCreateTestBiz() {
        
        log.info("批量创建测试业务");
        
        List<TestBizEntity> entityList = new ArrayList<>();
        for (int i = 1; i <= 5; i++) {
            TestBizEntity entity = new TestBizEntity();
            entity.setBizName("批量测试业务" + i);
            entity.setBizCode("BATCH_" + System.currentTimeMillis() + "_" + i);
            entity.setBizType(1);
            entity.setStatus(1);
            entity.setDescription("这是批量创建的测试业务" + i);
            entityList.add(entity);
        }
        
        boolean success = testBizService.saveBatch(entityList);
        
        Map<String, Object> response = new HashMap<>();
        if (success) {
            response.put("code", 200);
            response.put("message", "批量创建成功");
            response.put("data", entityList);
        } else {
            response.put("code", 500);
            response.put("message", "批量创建失败");
            response.put("data", null);
        }
        response.put("dataSource", "master");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 数据源测试接口 - 演示读写分离
     */
    @GetMapping("/test-datasource")
    @Operation(summary = "测试数据源", description = "测试读写分离，先查询从库，再写入主库，最后再查询从库")
    public ResponseEntity<Map<String, Object>> testDataSource() {
        
        log.info("开始测试数据源读写分离");
        
        Map<String, Object> testResult = new HashMap<>();
        
        // 1. 先从从库查询业务数量
        long countBefore = testBizServiceImpl.countTestBiz();
        testResult.put("countBefore", countBefore);
        testResult.put("step1", "从库查询业务数量：" + countBefore);
        
        // 2. 向主库插入一个测试业务
        TestBizEntity testEntity = new TestBizEntity();
        testEntity.setBizName("数据源测试业务");
        testEntity.setBizCode("TEST_" + System.currentTimeMillis());
        testEntity.setBizType(1);
        testEntity.setStatus(1);
        testEntity.setDescription("用于测试数据源读写分离的业务");
        testEntity.setCreateTime(LocalDateTime.now());
        testEntity.setUpdateTime(LocalDateTime.now());
        
        boolean saveResult = testBizService.save(testEntity);
        testResult.put("saveResult", saveResult);
        testResult.put("step2", "主库插入业务：" + (saveResult ? "成功" : "失败"));
        testResult.put("newEntityId", testEntity.getId());
        
        // 3. 再从从库查询业务数量（可能因为主从延迟，数量暂时不变）
        long countAfter = testBizServiceImpl.countTestBiz();
        testResult.put("countAfter", countAfter);
        testResult.put("step3", "从库查询业务数量：" + countAfter);
        
        // 4. 从主库查询刚插入的业务（应该能查到）
        TestBizEntity entityFromMaster = testBizService.getById(testEntity.getId());
        testResult.put("step4", "主库查询新业务：" + (entityFromMaster != null ? "成功" : "失败"));
        
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200);
        response.put("message", "数据源测试完成");
        response.put("data", testResult);
        response.put("timestamp", System.currentTimeMillis());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    @Operation(summary = "健康检查", description = "检查服务健康状态")
    public ResponseEntity<Map<String, Object>> health() {
        
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("service", "test-biz-service");
        response.put("timestamp", System.currentTimeMillis());
        response.put("version", "1.0.0");
        
        return ResponseEntity.ok(response);
    }
} 